package microcredit.gui.editor.loan;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import microcredit.gui.base.BaseAction;
import microcredit.gui.editor.AbstractEditorForm;
import microcredit.gui.handler.MemberHandler;
import microcredit.gui.selector.IFilter;
import microcredit.gui.table.BeanTable;
import microcredit.gui.table.TableFactory;
import microcredit.gui.util.ExceptionDialog;
import microcredit.gui.util.FormatUtilities;
import microcredit.gui.util.MemberEditorField;
import microcredit.gui.util.NumericTextField;
import microcredit.model.Member;
import microcredit.model.MemberToLoan;
import microcredit.model.MemberToLoanEntry;
import microcredit.model.MemberToLoanHistory;
import microcredit.model.ValidationException;
import microcredit.model.bo.BOLoan;
import microcredit.model.bo.BOMember;
import microcredit.model.domain.LoanStatus;
import microcredit.model.util.ModelUtils;
import net.miginfocom.swing.MigLayout;

import com.jidesoft.swing.JideButton;

public class LoanGeneralForm extends AbstractEditorForm<MemberToLoan> {
	private JScrollPane scrollPane;
	
	private BeanTable<MemberToLoanEntry> beanTable;
	private JLabel lblAmount;
	private JLabel lblReturnedAmount;
	private JTextField returnAmountTextField;
	private JTextField returnedAmountTextField;
	
	private MemberToLoan loan;
	private boolean updating;
	private boolean selectionUpdating;
	private MemberEditorField security1Field;
	private JLabel security1Label;
	private JLabel lblSecurity;
	private JLabel lblSecurity_1;
	private MemberEditorField security2Field;
	private MemberEditorField security3Field;
	private JPanel statisticPanel;
	private JLabel outstandingLabel;
	private JTextField outstandingTextField;
	
	
	private final ChangeLoanAction changeLoanAction = new ChangeLoanAction(this);
	private final SecurityRepaidAction securityRepaidAction = new SecurityRepaidAction(this);
	private final CancelledDeadAction cancelledDeadAction = new CancelledDeadAction(this);
	private final FillPaidAmountAction fillPaidAmountAction = new FillPaidAmountAction(this);
	private final ClearPaidAmountAction clearPaidAmountAction = new ClearPaidAmountAction(this);
	
	private MToolBar buttonPanel;
	private LoanPanel loanPanel;
	
	private ToggleActionButton securityRepaidToggleButton;
	private ToggleActionButton cancelledDeadToggleButton;
	private JScrollPane loanDataScrollPane;
	private JPanel loanDataPanel;
	private JideButton btnTakeover;
	private JideButton btnClearAmount;
	
	public LoanGeneralForm() {
		super();
		setTitle("General");
		initialize();
		TableFactory.fill(getBeanTable(), MemberToLoanEntry.class);
		
		
		initListeners();
		initActions();
	}
	
	public void removeLastExtension() {
		dataChanged();
		BOLoan.create().removeLastExtension(loan);
		apply(loan);
	}
	
	@Override
	public void focusDefault() {
		if (getLoanPanel().isVisible() && getLoanPanel().isEditable()) {
			getLoanPanel().focusDefault();
		} else {
			if (loanExtensionPanels != null && loanExtensionPanels.size() > 0) {
				loanExtensionPanels.get(loanExtensionPanels.size()-1).focusDefault();
			}
		}
	}
	
	@Override
	public MemberToLoan receive(MemberToLoan element) {
		try {
			Number n = getLoanNumberTextField().getNumberValue();
			if (n != null) {
				long longValue = n.longValue();
				longValue--;
				loan.setCustomSequenceID(longValue);
			}
		} catch (ParseException e) {
		}
		
		
		// apply security members
		Member security1 = getSecurity1Field().getElement();
		Member security2 = getSecurity2Field().getElement();
		Member security3 = getSecurity3Field().getElement();
		List<Member> securities = new ArrayList<Member>();
		if (security1 != null) {
			securities.add(security1);
		}
		if (security2 != null) {
			securities.add(security2);
		}
		if (security3 != null) {
			securities.add(security3);
		}
		element.setSecurity1(securities.size() > 0 ? securities.get(0) : null);
		element.setSecurity2(securities.size() > 1 ? securities.get(1) : null);
		element.setSecurity3(securities.size() > 2 ? securities.get(2) : null);
		
		element = getLoanPanel().receive(element, element.getLastHistory());
		
		int index = 1;
		for (LoanExtensionPanel panel : loanExtensionPanels) {
			panel.receive(element, element.getValidMemberToLoanHistories().get(index));
			index++;
		}
		
		return element;
	}

	@Override
	public boolean onSave(MemberToLoan element) throws Throwable {
		boolean superValue = super.onSave(element);
		return superValue;
	}
	
	@Override
	public void afterSave(MemberToLoan element) throws Throwable {
		if (element.areAllEntriesFinalized()
				&& !element.isFinalized()
				&& ModelUtils.compare(element.getReturnAmount(), element.getAmountPaid()) > 0 ) {
			// if all entries are finalized but amount is not paid autoextend the loan
			String message = "The loan is not yet paid, but no more loan rates are available.\n\nDo you want to extend the loan?";
			int result = JOptionPane.showConfirmDialog(this, message);
			if (result == JOptionPane.YES_OPTION) {
				emulateAction(changeLoanAction);
			}
		}
		
	}
	
	private List<LoanExtensionPanel> loanExtensionPanels;
	private JLabel statusLabel;
	private JLabel statusValueLabel;
	private NumericTextField loanNumberTextField;
	private JLabel loanNumberLabel;
	
	@Override
	public void apply(MemberToLoan element) {
		this.loan = element;
		updating = true;
		try {
			
			updateStatus(element);
			
			getLoanNumberTextField().setEditable(loan.isNew());
			getLoanNumberTextField().setEnabled(loan.isNew());
			
			Long loanNumber = loan.getSequenceID();
			
			if (loan.getCustomSequenceID()!=null) {
				loanNumber = loan.getCustomSequenceID();
			}
			if (loanNumber == null) {
				loanNumber = BOLoan.create().generateSequenceID(loan.getMember());
			}
			if (loanNumber != null) {
				loanNumber = loanNumber+1;
			}
			if (loanNumber != null) {
				LoanPanel.updateNumericTextField(getLoanNumberTextField(), loanNumber);
			}
			
			getSecurity1Field().setElement(element.getSecurity1());
			getSecurity2Field().setElement(element.getSecurity2());
			getSecurity3Field().setElement(element.getSecurity3());
			
			getLoanPanel().apply(element, element.getInitialHistory());
			updateExtensionPanels(element);
			
			int index = 1;
			List<MemberToLoanHistory> histories = element.getValidMemberToLoanHistories();
			for (LoanExtensionPanel panel : loanExtensionPanels) {
				panel.apply(element, histories.get(index));
				index++;
			}
			
			securityRepaidToggleButton.setSelected(element.getLoanStatus() == LoanStatus.R || element.getLoanStatus() == LoanStatus.K);
			cancelledDeadToggleButton.setSelected(element.getLoanStatus() == LoanStatus.N);
			
			updateAmounts(element);
			updateEntries(element);
			
			updateState();
		} finally {
			updating = false;
		}

	}
	
	private void updateStatus(MemberToLoan loan) {
		LoanStatus status = loan.getLoanStatus();
		getStatusValueLabel().setText(loan.createStatusString());
		if (status != null) {
			switch (status) {
			case A :
				getStatusValueLabel().setForeground(Color.BLUE);
				break;
			case F :
				getStatusValueLabel().setForeground(Color.decode("#166d18"));
				break;
			case N :
				getStatusValueLabel().setForeground(Color.RED);
				break;
			case R :
				getStatusValueLabel().setForeground(Color.decode("#8e8a23"));
				break;
			case K :
				getStatusValueLabel().setForeground(Color.decode("#166d18"));
				break;
			}
		}
	}

	private void updateExtensionPanels(MemberToLoan element) {
		int extensionCount = 0;
		if (element.getValidMemberToLoanHistories() != null) {
			extensionCount = element.getValidMemberToLoanHistories().size()-1;
		}
		
		if (loanExtensionPanels == null || loanExtensionPanels.size() != extensionCount) {
			if (loanExtensionPanels == null) {
				loanExtensionPanels = new ArrayList<LoanExtensionPanel>(extensionCount);
			}
			
			for (LoanExtensionPanel panel : loanExtensionPanels) {
				getLoanDataPanel().remove(panel);
			}
			getLoanDataPanel().removeAll();
			
			loanExtensionPanels.clear();
			
			for (int i = 0; i < extensionCount; i++) {
				LoanExtensionPanel panel = new LoanExtensionPanel(this);
				loanExtensionPanels.add(0, panel);
				getLoanDataPanel().add(panel, "growx");
			}
			getLoanDataPanel().add(getLoanPanel(), "growx");
		}
		
	}
	
	
	private void updateEntries(MemberToLoan element) {
		List<MemberToLoanEntry> entries = element.getMemberToLoanEntries();
		if (entries == null) {
			getBeanTable().load(entries);
		} else {
			getBeanTable().load(entries.subList(0, element.getSafeNumberOfWeeks()));
		}
	}
	
	private void updateAmounts(MemberToLoan element) {
		try {
			BOLoan.create().generateLoanEntries(element);
		} catch (ValidationException e) {
			ExceptionDialog.handleException(this, e);
		}
		getReturnAmountTextField().setText(FormatUtilities.formatMoney(element.getReturnAmount()));
		getReturnedAmountTextField().setText(FormatUtilities.formatMoney(element.getAmountPaid()));
		getOutstandingTextField().setText(FormatUtilities.formatMoney(element.getOutstandingAmount()));
	}
	protected void securityRepaid() throws Exception {
		loan = receive(loan);
		try {
			BOLoan.create().toggleAsSecurityPaid(loan);
		} finally {
			apply(loan);
		}
	}
	
	protected void cancelled() throws Exception {
		loan = receive(loan);
		try {
			BOLoan.create().toggleAsCancelled(loan);
		} finally {
			apply(loan);
		}
	}
	
	protected void extendLoan() throws Exception {
		loan = receive(loan);
		try {
			BOLoan.create().generateExtension(loan);
		} finally {
			apply(loan);
		}
	}
	
	void dataChanged() {
		if (!updating) {
			loan = receive(loan);
			try {
				BOLoan.create().generateLoanEntries(loan);
			} catch (Throwable e) {
				ExceptionDialog.handleException(this, e);
			}
			apply(loan);
			updateState();
//			updateEntries(loan);
		}
	}

	@Override
	public Dimension getDefaultSize() {
		return new Dimension(760, 600);
	}
	
	private void initActions() {
		
		addAction(changeLoanAction);
		addAction(securityRepaidAction);
		addAction(cancelledDeadAction);
		
		getButtonPanel().addAction(changeLoanAction);
		securityRepaidToggleButton = getButtonPanel().addToggleAction(securityRepaidAction);
		cancelledDeadToggleButton = getButtonPanel().addToggleAction(cancelledDeadAction);
		
		getBtnClearAmount().setAction(clearPaidAmountAction);
		getBtnTakeover().setAction(fillPaidAmountAction);
		
	}
	
	private void initListeners() {
		getBeanTable().getBeanModel().addTableModelListener(new TableModelListener() {
			@Override
			public void tableChanged(TableModelEvent e) {
				dataChanged();
//				updateAmounts(receive(loan));
			}
		});
		
		getBeanTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				selectionUpdated();
			}
		});
		getBeanTable().getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				selectionUpdated();
			}
		});
		getLoanNumberTextField().getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void removeUpdate(DocumentEvent e) {
				dataChanged();
			}
			@Override
			public void insertUpdate(DocumentEvent e) {
				dataChanged();
			}
			@Override
			public void changedUpdate(DocumentEvent e) {
				dataChanged();
			}
		});
	}
	

	private void selectionUpdated() {
		if (!selectionUpdating) {
			try {
				selectionUpdating = true;
				if (!getBeanTable().hasFocus()) {
					return;
				}
				int row = getBeanTable().getSelectedRow();
				int column = getBeanTable().getSelectedColumn();
				int editingRow = getBeanTable().getEditingRow();
				int editingColumn = getBeanTable().getEditingColumn();
				
				int modelColumn = getBeanTable().convertColumnIndexToModel(column);
				
				if (modelColumn == 4 && row == editingRow && column == editingColumn) {
					return;
				}
				int newRow = row;
				int newColumn = getBeanTable().convertColumnIndexToView(4);
				
				if (newRow == -1 || newColumn == -1) {
					return;
				}
				
				if (getBeanTable().isCellEditable(newRow, newColumn)) {
					getBeanTable().getColumnModel().getSelectionModel().clearSelection();
					getBeanTable().getColumnModel().getSelectionModel().setSelectionInterval(newColumn, newColumn);
//					getBeanTable().editCellAt(newRow, newColumn);
				}
				
//				if (getBeanTable().getEditorComponent() != null) {
//					getBeanTable().getEditorComponent().requestFocus();
//					((JTextComponent)getBeanTable().getEditorComponent()).selectAll();						
//				}
			} finally {
				selectionUpdating = false;
			}
		}
	}
	
	private void initialize() {
		setLayout(new MigLayout("insets 0 8 5 5, hidemode 3", "[pref!,right][230!][pref!][50!][grow][grow][grow]", "[][][][][][][][grow]"));
		add(getButtonPanel(), "cell 0 1 2 1,grow");
		add(getStatusLabel(), "cell 0 3");
		add(getStatusValueLabel(), "cell 1 3");
		add(getLoanNumberLabel(), "cell 2 3");
		add(getLoanNumberTextField(), "cell 3 3,growx");
		add(getStatisticPanel(), "cell 4 3 1 2,grow");
		add(getSecurity1Label(), "cell 0 4");
		add(getSecurity1Field(), "cell 1 4 3 1,grow");
		add(getLblSecurity(), "cell 0 5");
		add(getSecurity2Field(), "cell 1 5 3 1,grow");
		add(getScrollPane(), "cell 4 5 1 3,grow");
		add(getLblSecurity_1(), "cell 0 6");
		add(getSecurity3Field(), "cell 1 6 3 1,grow");
		add(getLoanDataScrollPane(), "cell 0 7 4 1,grow");
	}
	
	public BeanTable<MemberToLoanEntry> getBeanTable() {
		if (beanTable == null) {
			beanTable = new BeanTable<MemberToLoanEntry>();
			beanTable.setName(MemberToLoan.PAYMENT);
			beanTable.setAutoCreateRowSorter(false);
			beanTable.setRowSorter(null);
			beanTable.setFont(beanTable.getFont().deriveFont(9f));
			beanTable.getTableHeader().setFont(beanTable.getTableHeader().getFont().deriveFont(9f));
		}
		return beanTable;
	}
	private JLabel getLblAmount() {
		if (lblAmount == null) {
			lblAmount = new JLabel("To Return:");
		}
		return lblAmount;
	}
	private JLabel getLblReturnedAmount() {
		if (lblReturnedAmount == null) {
			lblReturnedAmount = new JLabel("Returned:");
		}
		return lblReturnedAmount;
	}

	private JScrollPane getScrollPane() {
		if (scrollPane == null) {
			scrollPane = new JScrollPane();
			scrollPane.setViewportView(getBeanTable());
			scrollPane.setName("scrollPane");
		}
		return scrollPane;
	}

	private JTextField getReturnAmountTextField() {
		if (returnAmountTextField == null) {
			returnAmountTextField = new JTextField();
			returnAmountTextField.setBackground(new Color(UIManager.getColor("control").getRGB()));
			returnAmountTextField.setEditable(false);
			returnAmountTextField.setColumns(5);
			returnAmountTextField.setRequestFocusEnabled(false);
		}
		return returnAmountTextField;
	}
	private JTextField getReturnedAmountTextField() {
		if (returnedAmountTextField == null) {
			returnedAmountTextField = new JTextField();
			returnedAmountTextField.setBackground(new Color(UIManager.getColor("control").getRGB()));
			returnedAmountTextField.setEditable(false);
			returnedAmountTextField.setColumns(5);
			returnedAmountTextField.setRequestFocusEnabled(false);
		}
		return returnedAmountTextField;
	}
	private MemberEditorField getSecurity1Field() {
		if (security1Field == null) {
			MemberHandler handler = new RestrictedMemberHandler(this, 0);
			security1Field = new MemberEditorField(null, handler, handler, handler, handler);
			security1Field.setName(MemberToLoan.SECURITY1);
		}
		return security1Field;
	}
	private JLabel getSecurity1Label() {
		if (security1Label == null) {
			security1Label = new JLabel("Security 1:");
		}
		return security1Label;
	}
	private JLabel getLblSecurity() {
		if (lblSecurity == null) {
			lblSecurity = new JLabel("Security 2:");
		}
		return lblSecurity;
	}
	private JLabel getLblSecurity_1() {
		if (lblSecurity_1 == null) {
			lblSecurity_1 = new JLabel("Security 3:");
		}
		return lblSecurity_1;
	}
	private MemberEditorField getSecurity2Field() {
		if (security2Field == null) {
			MemberHandler handler = new RestrictedMemberHandler(this, 1);
			security2Field = new MemberEditorField(null, handler, handler, handler, handler);
		}
		return security2Field;
	}
	private MemberEditorField getSecurity3Field() {
		if (security3Field == null) {
			MemberHandler handler = new RestrictedMemberHandler(this, 2);
			security3Field = new MemberEditorField(null, handler, handler, handler, handler);
		}
		return security3Field;
	}
	
	
	private class RestrictedMemberHandler extends MemberHandler {

		private final int index;
		
		public RestrictedMemberHandler(Component parent, int index) {
			super(parent);
			this.index = index;
		}
		
		@Override
		public List<IFilter<Member>> getFilters() {
			List<IFilter<Member>> filters = super.getFilters();
			for (IFilter<Member> iFilter : filters) {
				if (iFilter instanceof MemberGroupFilter) {
					if (loan != null && loan.getMember() != null && loan.getMember().getGroup() != null) {
						((MemberGroupFilter) iFilter).setSelectedValue(loan.getMember().getGroup());
					}
				}
			}
			return filters;
		}
		
		private List<Member> getMembers() {
			List<Member> members = new ArrayList<Member>();
			members.add(getSecurity1Field().getElement());
			members.add(getSecurity2Field().getElement());
			members.add(getSecurity3Field().getElement());
			members.add(loan.getMember());
			return members;
		}
		
		@Override
		public List<Member> load() throws Throwable {
			List<Member> readMembers = BOMember.create().readActiveMembers();
			List<Member> alreadySelectedMembers = getMembers();
			int index = 0;
			for (Member member : alreadySelectedMembers) {
				if (index != this.index && member != null) {
					readMembers.remove(member);
				}
				index++;
			}
			return readMembers;
		}
	}
	private JPanel getStatisticPanel() {
		if (statisticPanel == null) {
			statisticPanel = new JPanel();
			statisticPanel.setLayout(new MigLayout("insets 0", "[][grow][grow][grow][]", "[][][][]"));
			statisticPanel.add(getLblAmount(), "cell 1 1");
			statisticPanel.add(getLblReturnedAmount(), "cell 2 1");
			statisticPanel.add(getOutstandingLabel(), "cell 3 1");
			statisticPanel.add(getBtnClearAmount(), "flowy,cell 4 1 1 3,wrap");
			statisticPanel.add(getReturnAmountTextField(), "flowx,cell 1 2,growx");
			statisticPanel.add(getReturnedAmountTextField(), "cell 2 2,growx");
			statisticPanel.add(getOutstandingTextField(), "cell 3 2,growx");
			statisticPanel.add(getBtnTakeover(), "flowy,cell 4 1 1 3,wrap");
		}
		return statisticPanel;
	}
	private JLabel getOutstandingLabel() {
		if (outstandingLabel == null) {
			outstandingLabel = new JLabel("Outstanding:");
		}
		return outstandingLabel;
	}
	private JTextField getOutstandingTextField() {
		if (outstandingTextField == null) {
			outstandingTextField = new JTextField();
			outstandingTextField.setEditable(false);
			outstandingTextField.setColumns(5);
			outstandingTextField.setBackground(new Color(UIManager.getColor("control").getRGB()));
		}
		return outstandingTextField;
	}
	
	private class ChangeLoanAction extends BaseAction{

		public ChangeLoanAction(Component parent) {
			super(parent);
			setName("Extend loan");
			setIcon("x16/add2.png");
		}

		@Override
		public void perform(ActionEvent e) throws Throwable {
			extendLoan();
		}
		
		@Override
		public void updateState() throws Throwable {
			setEnabled(!loan.hasNewExtension() && loan.isEntryFinalized() && !loan.isFinalized());
		}
		
	}
	
	private class SecurityRepaidAction extends BaseAction{

		public SecurityRepaidAction(Component parent) {
			super(parent);
			setName("Security repaid");
			setIcon("x16/pin_yellow.png");
		}

		@Override
		public void perform(ActionEvent e) throws Throwable {
			securityRepaid();
		}
		
		@Override
		public void updateState() throws Throwable {
			setEnabled(!loan.isFinalized() || loan.getLoanStatus() == LoanStatus.R);
		}
	}
	
	private class CancelledDeadAction extends BaseAction{
		public CancelledDeadAction(Component parent) {
			super(parent);
			setName("Cancelled not repaid (dead)");
			setIcon("x16/pin_red.png");
		}

		@Override
		public void perform(ActionEvent e) throws Throwable {
			cancelled();
		}
		
		@Override
		public void updateState() throws Throwable {
			setEnabled(!loan.isFinalized()|| loan.getLoanStatus() == LoanStatus.N);
		}
	}
	
	private class FillPaidAmountAction extends BaseAction {
		public FillPaidAmountAction(Component parent) {
			super(parent);
			setName("");
			setIcon("x16/check2.png");
		}

		@Override
		public void perform(ActionEvent e) throws Throwable {
			List<MemberToLoanEntry> entries = getBeanTable().getSelectedElements();
			boolean modified = false;
			if (entries != null) {
				BigDecimal outstanding = loan.getOutstandingAmount();
				for (MemberToLoanEntry entry : entries) {
					if (entry.getLocked() == null || entry.getLocked().booleanValue() == false) {
						modified =true;
						BigDecimal amount = entry.getAmount();
						if (ModelUtils.compare(amount, outstanding) > 0) {
							amount = outstanding;
						}
						outstanding = outstanding.subtract(amount);
						entry.setAmountPaid(amount);
					}
				}
			}
			if (modified){
				dataChanged();
			}
		}
		
		@Override
		public void updateState() throws Throwable {
			List<MemberToLoanEntry> entries = getBeanTable().getSelectedElements();
			setEnabled(entries != null && entries.size() > 0);
		}
	}
	
	private class ClearPaidAmountAction extends BaseAction {
		public ClearPaidAmountAction(Component parent) {
			super(parent);
			setName("");
			setIcon("x16/eraser.png");
		}

		@Override
		public void perform(ActionEvent e) throws Throwable {
			List<MemberToLoanEntry> entries = getBeanTable().getSelectedElements();
			boolean modified = false;
			if (entries != null) {
				for (MemberToLoanEntry entry : entries) {
					if (entry.getLocked() == null || entry.getLocked().booleanValue() == false) {
						modified =true;
						entry.setAmountPaid(null);
					}
				}
			}
			if (modified){
				dataChanged();
//				getBeanTable().tableChanged(new TableModelEvent(getBeanTable().getModel()));
//				notifyDirty();
			}
		}
		
		@Override
		public void updateState() throws Throwable {
			List<MemberToLoanEntry> entries = getBeanTable().getSelectedElements();
			setEnabled(entries != null && entries.size() > 0);
		}
	}
	
	
	private MToolBar getButtonPanel() {
		if (buttonPanel == null) {
			buttonPanel = new MToolBar();
			buttonPanel.setInsetsEnabled(false);
		}
		return buttonPanel;
	}
	private LoanPanel getLoanPanel() {
		if (loanPanel == null) {
			loanPanel = new LoanPanel(this);
			loanPanel.setPreferredSize(new Dimension(20, 28));
		}
		return loanPanel;
	}

	private JScrollPane getLoanDataScrollPane() {
		if (loanDataScrollPane == null) {
			loanDataScrollPane = new JScrollPane();
			loanDataScrollPane.setViewportView(getLoanDataPanel());
			loanDataScrollPane.getVerticalScrollBar().setUnitIncrement(20);
			loanDataScrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
		}
		return loanDataScrollPane;
	}
	private JPanel getLoanDataPanel() {
		if (loanDataPanel == null) {
			loanDataPanel = new JPanel();
			loanDataPanel.setLayout(new MigLayout("hidemode 3, insets 0, wrap, gap 0", "[grow]", "[]"));
		}
		return loanDataPanel;
	}
	private JideButton getBtnTakeover() {
		if (btnTakeover == null) {
			btnTakeover = new JideButton("");
			btnTakeover.setPreferredSize(new Dimension(30, 20));
			btnTakeover.setIcon(new ImageIcon(LoanGeneralForm.class.getResource("/microcredit/icons/x16/check2.png")));
		}
		return btnTakeover;
	}
	private JideButton getBtnClearAmount() {
		if (btnClearAmount == null) {
			btnClearAmount = new JideButton("");
			btnClearAmount.setPreferredSize(new Dimension(30, 20));
			btnClearAmount.setIcon(new ImageIcon(LoanGeneralForm.class.getResource("/microcredit/icons/x16/eraser.png")));
			btnClearAmount.setToolTipText("Clear amount");
		}
		return btnClearAmount;
	}
	private JLabel getStatusLabel() {
		if (statusLabel == null) {
			statusLabel = new JLabel("Status:");
		}
		return statusLabel;
	}
	private JLabel getStatusValueLabel() {
		if (statusValueLabel == null) {
			statusValueLabel = new JLabel("Pending");
			statusValueLabel.setFont(statusValueLabel.getFont().deriveFont(statusValueLabel.getFont().getStyle() | Font.BOLD, 14f));
		}
		return statusValueLabel;
	}
	private NumericTextField getLoanNumberTextField() {
		if (loanNumberTextField == null) {
			loanNumberTextField = new NumericTextField();
			loanNumberTextField.setColumns(3);
			loanNumberTextField.setName(MemberToLoan.SEQUENCE_ID);
		}
		return loanNumberTextField;
	}
	private JLabel getLoanNumberLabel() {
		if (loanNumberLabel == null) {
			loanNumberLabel = new JLabel("Loan No.:");
		}
		return loanNumberLabel;
	}

}
